package tests;

import static org.junit.Assert.*;

import java.util.GregorianCalendar;

import model.AppointmentDataModel;
import model.CategoryDataModel;

import org.junit.*;
import sql.SqlConnector;

/**
 * 07-01-2010
 * 
 * These are the main scenarios for appointments.
 * 
 * @author Timo Janssen
 */
public class TestSqlConnector {

	private static SqlConnector sql = null;

	/**
	 * Makes connection to the database.
	 * 
	 * @throws Exception
	 */
	@BeforeClass
	public static void setUpOnce() throws Exception {
		sql = new SqlConnector("test.db");
		sql.createTable();
	}

	/**
	 * 
	 * @throws Exception
	 */
	@After
	public void tearDown() throws Exception {

	}

	@Test
	/**
	 * This is to check if the createTable function works.
	 */
	public void testCreateTable(){
		assertEquals( 0, sql.selectAllAppointments().size());
	}

	@Test
	/**
	 * This to check if one record has been added in the database.
	 */
	public void testAddCategory(){
		//Add one category
		sql.addCategory("School");		
		//Make a new datamodel and try the selectQuery
		CategoryDataModel cDM = sql.selectCategory(1);

		assertEquals("School", cDM.getTitle());
		assertEquals(1, sql.selectAllCategories().size());
	}

	@Test
	/**
	 * This to check if the second record has been added in the database.
	 */
	public void testAddTwoCategories(){
		//Add one category
		sql.addCategory("Werk");
		//Make a new datamodel and try the selectQuery
		CategoryDataModel cDM = sql.selectCategory(2);

		assertEquals("Werk", cDM.getTitle());
		assertEquals(2, sql.selectAllCategories().size());		
	}

	@Test
	/**
	 * This test is to check if the update category function works.
	 */
	public void testUpdateCategory(){
		//Update the second category, select the changed category and print it out.
		sql.updateCategory(2, "Werkzaken");
		CategoryDataModel cDM = sql.selectCategory(2);
		assertEquals("Werkzaken", cDM.getTitle());
		assertEquals(2, sql.selectAllCategories().size());	
	}

	@Test
	/**
	 * This test is to check if the update category function works.
	 */
	public void testExistsCategory(){
		assertTrue(sql.categoryExists(1));
	}

	@Test
	/**
	 * This test is to check if the update category function works.
	 */
	public void testDeleteCategory(){
		sql.deleteCategory(1);
		//Check if the appointmentExists method works
		assertFalse(sql.categoryExists(1));		
	}

	@Test
	/**
	 * Check if one appointment is added.
	 */
	public void testAddOneAppointment(){	
		//Add eight appointments
		// A small appointment that takes one hour
		sql.addAppointment(new model.AppointmentDataModel(0, "SLB Gesprek", new GregorianCalendar(2010, 0, 10, 10, 0, 0), new GregorianCalendar(2010, 0, 10, 11, 0, 0),  "W151", "Maarten", sql.selectCategory(2) , "SLB gesprek met maarten"));

		AppointmentDataModel aDM = sql.selectAppointment(1);
		//Check if appointment 1 exists with the expected data.
		assertEquals("1   SLB Gesprek   W151   Maarten   SLB gesprek met maarten", aDM.getId() + "   " + aDM.getTitle() + "   " + aDM.getLocation() + "   " + aDM.getContact() + "   " + aDM.getDescription());
	}

	@Test
	/**
	 * This is to check if the records are added, after every record has been added, it checks if the first one is correct.
	 */
	public void testAddTwoAppointments(){	
		// A larger appointment, spread out on two days, that lasts 25 hours
		sql.addAppointment(new model.AppointmentDataModel(0, "GUI leren", new GregorianCalendar(2010, 0, 13, 10, 0, 0), new GregorianCalendar(2010, 0, 14, 11, 0, 0), "W308", "EIN1Va", sql.selectCategory(2), "MVC Bespreken"));

		AppointmentDataModel aDM = sql.selectAppointment(1);
		assertEquals("1   SLB Gesprek   W151   Maarten   SLB gesprek met maarten", aDM.getId() + "   " + aDM.getTitle() + "   " + aDM.getLocation() + "   " + aDM.getContact() + "   " + aDM.getDescription());
		assertEquals( 2, sql.selectAllAppointments().size());
	}

	@Test
	/**
	 * This is to check if the record has been edited.
	 */
	public void testUpdateAppointment(){
		sql.updateAppointment(new model.AppointmentDataModel(1, "SLB Gesprekken", new GregorianCalendar(2010, 0, 10, 10, 0, 0), new GregorianCalendar(2010, 0, 10, 11, 0, 0),  "W152", "Michel", sql.selectCategory(1) , "SLB gesprek met maarten"));
		AppointmentDataModel aDM = sql.selectAppointment(1);
		assertEquals("1   SLB Gesprekken   W152   Michel   SLB gesprek met maarten", aDM.getId() + "   " + aDM.getTitle() + "   " + aDM.getLocation() + "   " + aDM.getContact() + "   " + aDM.getDescription()); 
	}

	@Test
	/**
	 * This is to check if second record has been edited in the appointment table.
	 */
	public void testSecondUpdateAppointment(){
		//update the second, load datamodel, select record and check if it's like expected

		sql.updateAppointment(new model.AppointmentDataModel(2, "GUI geven", new GregorianCalendar(2010, 0, 13, 11, 0, 0), new GregorianCalendar(2010, 0, 14, 13, 0, 0), "W309", "EIN1Vb", sql.selectCategory(2), "MVC Bespreken en andere zaken"));
		AppointmentDataModel aDM = sql.selectAppointment(2);
		assertEquals("2   GUI geven   W309   EIN1Vb   MVC Bespreken en andere zaken", aDM.getId() + "   " + aDM.getTitle() + "   " + aDM.getLocation() + "   " + aDM.getContact() + "   " + aDM.getDescription());
	}

	@Test
	/**
	 * This is to check if the record exists.
	 */
	public void testExistsAppointment(){
		//Check if the appointmentExists method works
		assertTrue(sql.appointmentExists(1));
	}

	@Test
	/**
	 * This is to check if the appointment in range are returnable.
	 */
	public void testAppointmentInRange(){
		//TO-DO	
	}

	@Test
	/**
	 * This is to check if the search gives the correct results.
	 */
	public void testSearch(){
		for(AppointmentDataModel d : sql.search("SLB Gesprekken")){
			assertEquals("SLB Gesprekken", d.getTitle());
		}
	}

	@Test
	/**
	 * This is to check if the results are in range.
	 */
	public void testInRange(){

		//Test unsuccesfull, TO-DO
	}

	@Test
	/**
	 * This is to check if the appointment has been deleted.
	 */
	public void testDeleteAppointment(){
		sql.deleteAppointment(1);
		//Check if the appointmentExists method works
		assertFalse(sql.appointmentExists(1));
	}
}